package name.ekr.assetguide.services;

import java.util.Arrays;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

import name.ekr.assetguide.data.DataLogger;
import name.ekr.assetguide.data.PriceIterator;
import name.ekr.assetguide.domain.Portfolio;
import name.ekr.assetguide.domain.RebalancedPortfolio;
import name.ekr.assetguide.domain.StaticPortfolio;

public class PortfolioGenerator {

	private BlockingQueue<Portfolio> queue = new LinkedBlockingQueue<Portfolio>();

	private PriceIterator iterator;
	private DataLogger logger;
	
	private static final int DELTA = 1;
	private static final int MAX = 10;

	
	public PortfolioGenerator(PriceIterator iterator, DataLogger logger) {
		this.iterator = iterator;
		this.logger = logger;
	}
	
	public void generatePortfolios() throws InterruptedException {
		generateDataSet(5, 0, 0, 0, 0, 0, 0);
	}
	
	public Portfolio getNextPortfolio() {
		return queue.poll();
	}
	
	
	private void generateDataSet(int currentElement, int... sourceDataSet) throws InterruptedException {
		int[] dataSet = Arrays.copyOf(sourceDataSet, sourceDataSet.length);
		int[] tail  = Arrays.copyOfRange(dataSet, currentElement, dataSet.length);
		int sumOfTail = sumOfArray(tail);
		
		if(currentElement == 0) {
			dataSet[currentElement] = MAX - sumOfTail;
			savePortfolioWithDataSet(dataSet);
			return;
		}
		
		for(int i = 0; i <= MAX - sumOfTail; i+= DELTA) {
			generateDataSet(currentElement-1, dataSet);
			dataSet[currentElement] += DELTA;
		}
			
	}

	private void savePortfolioWithDataSet(int... dataSet) throws InterruptedException {
//		queue.put( new StaticPortfolio(iterator, logger,
//				dataSet[0]/10., dataSet[1]/10., dataSet[2]/10.,
//				dataSet[3]/10., dataSet[4]/10., dataSet[5]/10.
//				)
//		);
        queue.put( new RebalancedPortfolio(iterator, logger,
                dataSet[0]/10., dataSet[1]/10., dataSet[2]/10.,
                dataSet[3]/10., dataSet[4]/10., dataSet[5]/10.
        )
        );
	}

	private static int sumOfArray(int... array) {
		if(array.length == 0) return 0;
		if(array.length == 1) return array[0];
		return array[array.length-1] + sumOfArray(Arrays.copyOf(array, array.length - 1));
	}
	
}
